// 改进StreamSpeech组件 - 解决播放错误问题
import { useEffect, useRef, useState } from 'react';

interface StreamSpeechProps {
  text: string;
  onComplete?: () => void;
  onError?: (error: Error) => void;
}

const StreamSpeech: React.FC<StreamSpeechProps> = ({
  text,
  onComplete,
  onError
}) => {
  console.log("StreamSpeech组件渲染，接收文本:", text);
  
  // 组件挂载和卸载日志
  useEffect(() => {
    console.log("StreamSpeech组件挂载");
    return () => {
      console.log("StreamSpeech组件卸载");
    };
  }, []);

  // 使用ref跟踪组件状态
  const isSynthesizingRef = useRef<boolean>(false);
  // 最近一次合成的文本
  const lastTextRef = useRef<string>('');
  // 避免重复回调
  const callbackTriggeredRef = useRef<boolean>(false);
  
  useEffect(() => {
    // 仅在文本发生变化且非空时执行
    if (!text || text === lastTextRef.current || isSynthesizingRef.current) {
      console.log('StreamSpeech: 跳过处理', {
        noText: !text, 
        sameAsPrevious: text === lastTextRef.current, 
        alreadySynthesizing: isSynthesizingRef.current
      });
      return;
    }
    
    // 更新最近一次文本
    lastTextRef.current = text;
    
    // 标记为正在合成
    isSynthesizingRef.current = true;
    callbackTriggeredRef.current = false;
    
    console.log('StreamSpeech: 开始处理文本:', text);
    
    // 直接使用同步合成API
    synthesizeAndPlay(text)
      .catch(err => {
        console.error('StreamSpeech: 语音合成或播放失败:', err);
        if (onError && !callbackTriggeredRef.current) {
          callbackTriggeredRef.current = true;
          onError(err instanceof Error ? err : new Error(String(err)));
        }
      })
      .finally(() => {
        // 合成完成
        console.log('StreamSpeech: 合成操作完成');
        isSynthesizingRef.current = false;
      });
      
    // 组件卸载时清理
    return () => {
      console.log('StreamSpeech: 组件卸载，清理资源');
      // 尝试停止所有正在播放的音频
      document.querySelectorAll('audio[data-stream-speech="true"]').forEach((el) => {
        try {
          (el as HTMLAudioElement).pause();
          document.body.removeChild(el);
        } catch (e) {
          console.error('清理音频元素失败:', e);
        }
      });
    };
  }, [text, onComplete, onError]);
  
  // 合成并播放语音
  const synthesizeAndPlay = async (text: string) => {
    try {
      // 获取音频blob
      const audioBlob = await fetchSynthesizeAPI(text);
      if (!audioBlob) {
        throw new Error('获取音频失败');
      }
      
      // 创建URL
      const audioUrl = URL.createObjectURL(audioBlob);
      
      // 使用DOM API创建并播放音频
      const audioElement = document.createElement('audio');
      audioElement.setAttribute('data-stream-speech', 'true');
      audioElement.style.display = 'none';
      
      // 确保音频加载完毕
      audioElement.onloadedmetadata = () => {
        console.log(`音频加载完成，时长: ${audioElement.duration}秒`);
      };
      
      // 监听播放进度
      audioElement.ontimeupdate = () => {
        // 可以添加日志查看播放进度
        // console.log(`播放进度: ${audioElement.currentTime}/${audioElement.duration}`);
      };
      
      // 监听播放结束事件 - 关键部分
      audioElement.onended = () => {
        console.log('音频播放结束，触发完成回调');
        
        // 清理资源
        URL.revokeObjectURL(audioUrl);
        try {
          document.body.removeChild(audioElement);
        } catch (e) {
          console.error('移除音频元素失败:', e);
        }
        
        // 确保回调只触发一次
        if (onComplete && !callbackTriggeredRef.current) {
          callbackTriggeredRef.current = true;
          console.log('正在触发onComplete回调');
          onComplete();
        }
      };
      
      // 监听错误事件
      audioElement.onerror = (e) => {
        console.error('音频播放错误:', e);
        URL.revokeObjectURL(audioUrl);
        try {
          document.body.removeChild(audioElement);
        } catch (err) {
          console.error('移除音频元素失败:', err);
        }
        
        if (onError && !callbackTriggeredRef.current) {
          callbackTriggeredRef.current = true;
          onError(new Error('音频播放失败'));
        }
      };
      
      // 设置属性并添加到DOM
      audioElement.src = audioUrl;
      document.body.appendChild(audioElement);
      
      // 添加辅助调试日志
      console.log('开始播放音频...');
      
      // 播放并等待完成
      const playPromise = audioElement.play();
      
      // 处理播放错误
      if (playPromise !== undefined) {
        await playPromise;
        console.log('音频开始播放');
      }
    } catch (error) {
      console.error('语音合成或播放失败:', error);
      throw error;
    }
  };
  
  // 调用普通合成API
  const fetchSynthesizeAPI = async (text: string): Promise<Blob | null> => {
    try {
      console.log('请求语音合成:', text.substring(0, 30) + (text.length > 30 ? '...' : ''));
      
      // 添加超时处理
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), 10000);
      
      const response = await fetch('https://teacher.dianchuang.club/api/synthesize', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ 
          text,
          voice_type: "1001",
          sample_rate: 16000
        }),
        signal: controller.signal
      });
      
      clearTimeout(timeoutId);
      
      if (!response.ok) {
        console.warn(`语音合成请求失败: ${response.status}`);
        return null;
      }
      
      const blob = await response.blob();
      console.log(`合成成功: ${blob.size} 字节`);
      return blob;
    } catch (error) {
      console.warn('语音合成请求出错:', error);
      return null;
    }
  };
  
  // 确保即使在组件卸载时也会触发回调
  useEffect(() => {
    return () => {
      // 组件卸载时，如果还没触发回调，则触发
      if (!callbackTriggeredRef.current && onComplete) {
        console.log("组件卸载时触发完成回调");
        callbackTriggeredRef.current = true;
        onComplete();
      }
    };
  }, [onComplete]);
  
  return null;
};

export default StreamSpeech;